/** @file    KioskManager.cpp
 *  @author  Alessandro Polo
 *  @version $Id: KioskManager.cpp 2821 2010-08-01 11:44:26Z alex $
 *  @brief
 * File containing methods for the wosh::gui::KioskManager class.
 * The header for this class can be found in KioskManager.h, check that file
 * for class description.
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/
 
 #include "KioskManager.h"

 #include <core/MethodsCommon.h>
 #include <core/MessageFilter.h>
 #include <core/MessageProcessingCommon.h>
 #include <core/SystemError.h>
 #include <core/UserManager.h>
 #include <core/WoshKernel.h>
 #include <framework/gui/GuiUtilities.h>

 #include <framework/security/SecurityAuthenticationOS.h>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef _OS_POSIX
# include <core/posix/desktop.h>
#endif
#ifdef _OS_WIN32
# include <core/win32/desktop.h>
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////


using namespace std;
namespace wosh {
 namespace gui {

KioskManager* KioskManager::instance = NULL;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS

KioskManager::KioskManager() : QObject(), Object()
 {
	this->layout = NULL;

	Object::setName("KioskManager");
	Object::getURI().fromString( ":KioskManager" );

	Log.setIndent( 3 );
	Log.setContext( "BundleGeneric" );
	Log.setLevel( LOG_INFO );

//Log.setLevel( LOG_VERBOSE );

	string wosh_user = "anomymous"; string os_user;
	WRESULT ret = wosh::security::SecurityTokenProviderOS::findLoggedUser(wosh_user, &os_user);
	if ( WFAILED(ret) )
		QMessageBox::critical(0, "KioskManager", tr("ERROR Retrieving current WOSH Username!\nForced 'anonymous'.\n\nOS User: %1").arg(wosh_user.c_str()) );

	GuiUtilities::getSessionInfo().transactionBeginWrite();
	GuiUtilities::getSessionInfo().setUsername(wosh_user);
	GuiUtilities::getSessionInfo().setCredentials( new wosh::security::SecurityTokenProviderOS() );
	GuiUtilities::getSessionInfo().transactionEnd();

	this->security = new KioskSecurity(this);
	connect(this->security, SIGNAL(userLoggedIn()), this, SLOT(security_userLoggedIn()));
	//connect(this->security, SIGNAL(userLoggedOut()), this, SLOT(security_userLoggedOut()));
	connect(this->security, SIGNAL(userAuthorizationFault()), this, SLOT(security_userAuthorizationFault()));

	Properties.set( "asd1",	10, Permission(Permission::Read) );
	Properties.set( "asd2",	1, Permission(Permission::Read) );
	Properties.set( _KEY_Version,		0.0, Permission(Permission::Read) );
	Properties.set( _KEY_DebugLevel,	LogContext::getLogLevelAsString(LOG_INFO), Permission(Permission::RW, Permission::Read, Permission::Read) );
	Properties.updateObjectKeys( this );
	Properties.setPermission( Object::getPermission(), Permission::Overwrite_All, true, true );
	Properties.setPropertiesProviderListener(this);

	// register default methods
	Methods.setPermission( Object::getPermission(), Permission::Overwrite_All, true, true );
	Methods.getListPermission().setMask( Permission::Read, Permission::Read, Permission::Read );

	MethodPropertyT::createMethods( &Methods, &Properties, &Log );

	MethodChT::createMethods( &Methods, this, &Properties, &Log );

	MethodMethodsList* mmMethodListing = Methods.create<MethodMethodsList>();
	mmMethodListing->setMethodsProvider( &Methods );
	mmMethodListing->setLogContext( &Log );


	KioskManager::instance = this;
 }

KioskManager::~KioskManager() {
	KioskManager::instance = NULL;
 }

//////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void KioskManager::init()
 {
	// register to BUS
	BusCore.setMessageHandler(this);
	WRESULT bus_connected = BusCore.connect( _Bus_Core );
	if ( WFAILED(bus_connected) )
		SystemError::raise(this, Log, SystemError::CRITICAL, 0, "init", "[CREATED] FAILED#%d Connecting Bus (wosh.Bus.Core)..", bus_connected );
 }

void KioskManager::setLayout( KioskLayout* Layout ) {
	this->layout = Layout;
	if ( this->layout == NULL ) {
		return;
	 }
	this->layout->setNavigatorListener(this);
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void KioskManager::registerSheet( KioskSheet* item ) {
	this->sheets.push_back(item);
	this->layout->setSheet( item->asQGraphicsWidget() );
 }

void KioskManager::registerGadget( KioskGadget* item ) {
	this->gadgets.push_back(item);
	this->layout->addGadget( item->asQGraphicsWidget() );
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void KioskManager::refreshView() {
	vector<KioskSheet*>::iterator its;
	for ( its=this->sheets.begin(); its!=this->sheets.end(); its++ ) {
		if ( *its == NULL ) continue;
		QGraphicsWidget* gw = (*its)->asQGraphicsWidget();
		if ( gw == NULL ) continue;
		if ( !gw->isVisible() ) continue;
		(*its)->refreshAll();
		break;
	 }
	vector<KioskGadget*>::iterator itg;
	for ( itg=this->gadgets.begin(); itg!=this->gadgets.end(); itg++ ) {
		if ( *itg == NULL ) continue;
		QGraphicsWidget* gw = (*itg)->asQGraphicsWidget();
		if ( gw == NULL ) continue;
		if ( !gw->isVisible() ) continue;
		(*itg)->refreshAll();
		break;
	 }
 }















//////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////// EVENTS

void KioskManager::itemSelected( NavigatorItem* item ) {
	if ( item == NULL ) return;

	if ( item->context == "KiosK::Command::StandBy" ) {
		logoff();
		return;
	 }

	KioskSheet* sheet = NULL;
	if ( !item->sheet_name.empty() ) {
		sheet = getSheetByName_(item->sheet_name);
	 }

	if ( sheet == NULL )
		sheet = getSheetByContext_(item->context);
	if ( sheet == NULL )
		return;
	this->layout->setSheet( sheet->asQGraphicsWidget() );
 }

////////////////////////////////////////////////////////////////////////////////////////////////////// EVENTS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////// EVENTS

bool KioskManager::updatingProperty( bool& , const Variant& , Property& , const PropertiesProvider* ) {
	return true;
 }

////////////////////////////////////////////////////////////////////////////////////////////////////// EVENTS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void KioskManager::busMessage( const Message& message, const Bus* source ) {

	if ( !MessageFilter::isMessageTarget(message, this) ) {
		return;
	 }
	if ( !message.getContent()->isRequest() ) {
		return;
	 }
	Message* reply = MPC_busMessageRequest( message, this->Methods, this->Log );
	if ( reply == NULL )
		return;

	reply->setSource( this );
	if ( source != NULL )
		source->postMessage(reply);
	else
		BusCore.postMessage(reply);
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

KioskSheet* KioskManager::getSheetByName_( const string& name ) {
	vector<KioskSheet*>::iterator it;
	for ( it=this->sheets.begin(); it!=this->sheets.end(); it++ ) {
		if ( *it == NULL ) continue;
		if ( (*it)->getName() != name ) continue;
		return *it;
	 }
	return NULL;
 }
KioskSheet* KioskManager::getSheetByContext_( const string& context ) {
	vector<KioskSheet*>::iterator it;
	for ( it=this->sheets.begin(); it!=this->sheets.end(); it++ ) {
		if ( *it == NULL ) continue;
		if ( (*it)->getContext() != context ) continue;
		return *it;
	 }
	return NULL;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////


  }; // namespace gui
}; // namespace wosh

